# atom.py
# Original Author: Amar Zumkhawala (amarzumkhawala@gmail.com)
# Project URL - http://code.google.com/p/feedflare-categories
# Distributed under Apache License 2.0
#
# $Revision: 31 $, $Date: 2009-01-11 05:02:49 +0000 (Sun, 11 Jan 2009) $
# $Author: amarzumkhawala $

import logging
from urlparse import urlparse
from xml.dom.minidom import parseString
from xmlutil import getText

"""Struct for relevant data from an atom entry"""
class AtomEntry:
  def blogUrl(self):
    return self._blogUrl
  def setBlogUrl(self,value):
    self._blogUrl = value
  def categories(self):
    return self._categories
  def setCategories(self,value):
    self._categories = value

"""
Atom Entry Parser.  Parses an Atom xml feed into an AtomEntry.
"""
class AtomEntryParser:
  """
  Parse the atom xml for the <category> and <link> tags of interest
  for an entry with the requested id.
  """
  def parse(self,atomEntryId,atomXml):
    blogUrl = None
    categories = []
    domain = None
    entry = None

    dom = parseString(atomXml)

    ids = dom.getElementsByTagName("id")

    # <atom:id> tags are 1:1 to <atom:entry> tags.   
    for id in ids:
      entry = id.parentNode
      entryId = getText(id).strip()
      if (entryId == atomEntryId):
        # get the categories        
        categoryTags = entry.getElementsByTagName('category')
        for category in categoryTags:
          term = category.attributes['term'].value
          categories.append(term)

        # find the blog url
        links = entry.getElementsByTagName('link')
        for link in links:
          rel = link.attributes['rel'].value
          if rel.startswith('alternate') :      
            href = link.attributes['href'].value
            url = urlparse(href)
            domain = url.hostname
            blogUrl = "http://" + domain + "/"
        
        if (domain == None):
          raise Exception("Could not find the domain for the entry: " + entry.toxml())

    if (domain == None):
      raise Exception("Could not find entry with id " + atomEntryId + " in "  + atomXml)
    
    logging.info("found " + str(len(categories)) + " category for atom entry from blog " + domain)
    atomEntry = AtomEntry()
    atomEntry.setBlogUrl(blogUrl)
    atomEntry.setCategories(categories)
    return atomEntry
